[modal] feature: update to native <dialog> with showModal()#154
Draft
[modal] feature: update to native <dialog> with showModal()#154
<dialog> with showModal()#154Conversation
|
Co-authored-by: marlonmarcello <[email protected]>
Copilot
AI
changed the title
[WIP] Update to use dialog and showModal method
[modal] feature: update to native Mar 18, 2026
<dialog> with showModal()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
The modal was using a
<div role="dialog">with a hand-rolled focus trap (sentinel elements + manual focus cycling). The native<dialog>element +showModal()handles focus trapping, top-layer stacking, and modal semantics natively — and is baseline-available in all modern browsers including Safari 15+.Solution
Replaced the
<div>modal container with<dialog>and callshowModal()on mount. This eliminates the need forModalFocusBounds,ModalVisuallyHidden, and all manual focus management code.Key decisions:
onCancelprevention:showModal()causes the browser to fire acancelevent on Escape and close the dialog natively. We calle.preventDefault()to keep React state in control — the existinguseModalEscape key listener handles state updates.showModal()places the element in the browser's top layer with fixed-position semantics, so the explicitposition: fixedclass on<Modal>is no longer needed and has been removed.ModalBackdroppreserved: The native::backdroppseudo-element is unused (transparent by default);ModalBackdropremains as the customizable overlay, positioned absolutely within the full-viewport dialog.Modal,ModalBackdrop,ModalContent, anduseModalsignatures are unchanged.Deleted (internal, not exported):
modal-focus-bounds/— custom circular focus trap sentinelsmodal-visually-hidden/— visually-hidden cycling elementsmodal.module.scss—.ModalFixed/.ModalAbsoluteclasses (no longer applied)CSS reset on
<dialog>to neutralise browser defaults:Additional Notes
Browser support:
<dialog>+showModal()has been baseline-available since Safari 15.4 (March 2022). No polyfill is required for the stated peer dependency range (React 17–19 implies modern browser targets).The
useModalEscape key listener (keyuponwindow) is intentionally kept — it remains valid for consumers who useuseModalindependently of<Modal>.Screenshots
N/A — layout and visual appearance are unchanged.
Original prompt
dialogandshowModal#114💬 Send tasks to Copilot coding agent from Slack and Teams to turn conversations into code. Copilot posts an update in your thread when it's finished.